package com.shuql.cloud.oauth2.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;

import javax.sql.DataSource;

/**
 * @author ：shuquanliang
 * @date ：Created in 2020/4/23 10:50
 * @description：
 */
@Configuration
public class TokenConfig {

    private static final String SIGNING_KEY = "SIGNING_KEY";

    /**
     * Redis管理令牌
     * 1、启动Redis管理器
     * 2、添加Redis相关依赖
     * 3、添加Redis依赖后，容器就会有RedisConnectionFactory实例
     * 4、在application.yml配置Redis
     */
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    /**
     * JDBC管理令牌
     * 1、创建相关数据表
     * 2、添加JDBC相关依赖
     * 3、配置数据源
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    /**
     * JWT转换器
     *
     * @return
     */
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        //对称加密进行签名令牌，资源服务器也要采用此秘钥进行解密
        //converter.setSigningKey(SIGNING_KEY);

        //采用非对称加密进行签名令牌
        //读取 oauth2.jks 文件中的私钥，第2个参数是口令 oauth2
        KeyStoreKeyFactory keyFactory = new KeyStoreKeyFactory(new ClassPathResource("oauth2.jks"),"oauth2".toCharArray());
        //别名oauth2
        converter.setKeyPair(keyFactory.getKeyPair("oauth2"));
        return converter;
    }

    @Bean
    public TokenStore tokenStore() {
        //Redis管理令牌
        //return new RedisTokenStore(redisConnectionFactory);
        //JDBC管理令牌
        //return new JdbcTokenStore(dataSource());
        //JWT管理令牌
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

}
